package ucd.wirelessnetworkmonitor;

import java.util.List;

import ucd.wirelessnetworkmonitor.R;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.TrafficStats;
import android.os.Bundle;
import android.os.Handler;
import android.telephony.NeighboringCellInfo;
import android.telephony.PhoneStateListener;
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
import android.telephony.gsm.GsmCellLocation;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;


public class CellularActivity extends Activity {
	
	private static final String TAG = "NETMON";
	TextView cellIdTextView;
	TextView cinrTextView;
	TextView connectionStatusTextView;
	TextView sentDataTextView;
	TextView receivedDataTextView;
	TextView neighbouringCellCountTextView;
	TelephonyManager telephonyManager;
	GsmCellLocation cellLocation;
	SignalStrengthListener signalListener;
	
	long sent;
	long received;
	long sentData;
	long receivedData;
	long totalSent;
	long totalReceived;
	Handler transmissionHandler;
	Handler neighboursHandler;
	
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_cellular);
		
        // Get references to widgets in layout
        cellIdTextView = (TextView) findViewById(R.id.cellIdTextView);
        cinrTextView = (TextView) findViewById(R.id.cinrTextView);
        connectionStatusTextView = (TextView) findViewById(R.id.connectionStatusTextView);
        sentDataTextView = (TextView) findViewById(R.id.sentDataTextView);
        receivedDataTextView = (TextView) findViewById(R.id.receivedDataTextView);
        neighbouringCellCountTextView = (TextView) findViewById(R.id.neighbouringCellCountTextView);
        
        // Get telephony service
		telephonyManager = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
		cellLocation = (GsmCellLocation) telephonyManager.getCellLocation();
		
		// Bind signal strength listener
		signalListener = new SignalStrengthListener();
		telephonyManager.listen(signalListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
		
		// Get cell ID and connection status
		getCellId();
		getConnectionStatus();
		
		// Get initial values for data sent and received
		// over interface and start handler to update these values.
		sentData = TrafficStats.getMobileTxBytes();
		receivedData = TrafficStats.getMobileRxBytes();
		transmissionHandler = new Handler();
		transmissionHandler.post(new Runnable() {

			public void run() {
				getCellId();
				getConnectionStatus();
				
				long oldTotalSent = totalSent;
				long oldTotalReceived = totalReceived;
				
				// Only counts traffic over cellular 
				totalSent = TrafficStats.getMobileTxBytes() - sentData;
				totalReceived = TrafficStats.getMobileRxBytes() - receivedData;
				
				long sentRate = totalSent - oldTotalSent;
				long receivedRate = totalReceived - oldTotalReceived;
				
				// Fixed bug causing negative transfered figures.
				
				Log.d(TAG, Long.toString(sentRate));
				Log.d(TAG, Long.toString(receivedRate));
				
				sentDataTextView.setText("Sent Data: " + Long.toString(totalSent) + " bytes ("
						+ sentRate/1024 + " kB/s)");
				receivedDataTextView.setText("Received Data: " + Long.toString(totalReceived) + " bytes ("
						+ receivedRate/1024 + " kB/s)");
				transmissionHandler.postDelayed(this, 1000);
			}
			
		});
		
		// Set handler to update neighbouring cell info
		// DOES NOT WORK ON SAMSUNG HANDSETS
		neighboursHandler = new Handler();
		neighboursHandler.post(new Runnable() {

			public void run() {
				List<NeighboringCellInfo> neighbouringCells = telephonyManager.getNeighboringCellInfo();
				neighbouringCellCountTextView.setText("Cell Count: " + neighbouringCells.size());
				
				for (NeighboringCellInfo cell : neighbouringCells) {
					neighbouringCellCountTextView.append("\n\nCell ID: " + cell.getCid());
					neighbouringCellCountTextView.append("\nRSSI: " + cell.getRssi());
				}
				
				neighboursHandler.postDelayed(this, 5000);
			}
		});
	}
	
	public void onPause() {
		super.onPause();
		telephonyManager.listen(signalListener, PhoneStateListener.LISTEN_NONE);
	}
	
	public void onResume() {
		super.onResume();
		telephonyManager.listen(signalListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
	}
	
	public boolean onCreateOptionsMenu(Menu menu) {
    	MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.cellular_options_menu, menu);
		return super.onCreateOptionsMenu(menu);
    }
    
    public boolean onMenuItemSelected(int id, MenuItem item) {
    	
    	switch(item.getItemId()) {
    	case R.id.cellular_menu_refresh:
    		Toast.makeText(this, "Refreshing cellular network info.",
    				Toast.LENGTH_LONG).show();
    		refreshCellularInfo();
    		return true;
    	case R.id.cellular_menu_about:
    		Intent intent = new Intent(this, AboutActivity.class);
    	    startActivity(intent);
    		return true;
    	default:
    		return super.onMenuItemSelected(id, item);
    	}
    }

    public void getConnectionStatus() {
    	// Get connection state
    	int connectionState = telephonyManager.getDataState();
    	Log.d(TAG, "Data Connection Status: " + Integer.toString(connectionState));
    	String connectionString = "";
    			
    	switch (connectionState) {
    	case TelephonyManager.DATA_CONNECTED:
    		connectionString = "Connected";
    		break;
    	case TelephonyManager.DATA_DISCONNECTED:
    		connectionString = "Disconnected";
    		break;
    	case TelephonyManager.DATA_CONNECTING:
    		connectionString = "Connecting";
    		break;
    	case TelephonyManager.DATA_SUSPENDED:
   			connectionString = "Suspended";
    		break;
    	default:
    		connectionString = "Status Unavailable";
    		break;
    	}
    			
    connectionStatusTextView.setText("Connection State: " + connectionString);
    }
    
    public void getCellId() {
    	int cellId = cellLocation.getCid();
		cellIdTextView.setText("Cell ID: " + Integer.toString(cellId));
    }
    
    public void refreshCellularInfo() {
    	getCellId();
    	getConnectionStatus();
    }
    
    private class SignalStrengthListener extends PhoneStateListener {
    	public void onSignalStrengthsChanged(SignalStrength signalStrength) {
    		super.onSignalStrengthsChanged(signalStrength);
    		
    		int cinr = signalStrength.getGsmSignalStrength();
    		cinrTextView.setText("CINR: " + cinr + " dBs");
    	}
    }
}
